/*
 * Created on Jul 7, 2006
 * 
 */

package com.probiz.estore.aop;

import java.util.Arrays;
import java.util.Collection;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.probiz.estore.common.helper.AppAuditHelper;
import com.probiz.estore.common.model.system.AuditInfo;
import com.probiz.estore.common.model.system.Auditable;
import com.probiz.estore.webapp.util.RequestContext;

/**
 * @author Legend
 * 
 */
public class AuditInterceptor implements MethodInterceptor {
	protected final transient Log	logger	= LogFactory.getLog(getClass());
	/*
	 * <pre> Audit very simple action, only audit actionName, procObj,
	 * SUCCESS/FAILED, requestUrl, etc. Use AuditHelper instead to audit more
	 * detailed info. </pre>
	 * 
	 * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
	 */
	public Object invoke(MethodInvocation methodInvocation) throws Throwable {
		 logger.debug("entering MethodInterceptor ......"+methodInvocation.getClass().getName()+"."+methodInvocation.getMethod().getName());
		String result = AppAuditHelper.RESULT_SUCCESS;
		try {
			return methodInvocation.proceed();
		} catch (Throwable e) {
			result = AppAuditHelper.RESULT_FAILED;
			throw e;
		} finally {

			Object[] args = methodInvocation.getArguments();
			String actionName = methodInvocation.getMethod().getName();
			
			// holds the detailed audit info
			StringBuffer buf = new StringBuffer();

			if (args != null) {
				if (args.length == 1) {
					Object entity = args[0];
					if (entity instanceof Auditable) {
						// An auditable entity, use detailed info from
						// getAuditInfo
						AuditInfo auditInfo = ((Auditable) entity).getAuditInfo(actionName);
						if (auditInfo != null) {
							if (auditInfo.getActionNameMappings() != null && auditInfo.getActionNameMappings().get(actionName) != null) {
								actionName = auditInfo.getActionNameMappings().get(actionName);
							}


							if (auditInfo.getEntityType() != null) {
								buf.append("[").append(auditInfo.getEntityType()).append("]: ");
							}
							buf.append(auditInfo.getEntityAuditInfo());

						}
					} else if (entity instanceof Collection) {
						Collection col = (Collection) entity;
						buf.append("Bulk update: " + col.size() + " "+ col.toString());
					} else {
						// usually is a BaseObject or some other POJO, apply
						// default seetings to get entity info
						buf.append(entity);
					}
				} else {
					// more than one arguments
					buf.append("Multiple arguments: " + Arrays.toString(args));
				}
			}// else no more detailed info need to audit
			if(actionName.indexOf("update")!=-1 || actionName.indexOf("save")!=-1){
				actionName = AppAuditHelper.ACTION_UPDATE;
			}else if(actionName.indexOf("delete")!=-1 || actionName.indexOf("remove")!=-1){
				actionName = AppAuditHelper.ACTION_DEL;
			}else{
				actionName = AppAuditHelper.ACTION_OTHER;
			}
		    AppAuditHelper.getInstance().doAuditAction(actionName, methodInvocation.toString()+" 对象："+buf.toString(), result, RequestContext.getCurrentHttpRequest().getRemoteAddr(),RequestContext.getCurrentUserName());

			logger.debug("leaving MethodInterceptor ...... "
			 +methodInvocation.getClass().getName()+"."+methodInvocation.getMethod().getName());
		}

	}


}
